﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClientSide
{
    #region Using

    using log4net;
    using System.Runtime.InteropServices;
    using System.Net;
    using System.Text.RegularExpressions;
    using System.Net.Sockets;
    
    #endregion

    public class Common
    {
        #region Variables

        /// <summary>
        /// Logger for logging
        /// </summary>
        public static readonly ILog Logger = LogManager.GetLogger(typeof(Common));

        #endregion

        #region Enums

        /// <summary>
        /// Server status enum
        /// </summary>
        public enum ServerStatus
        {
            /// <summary>
            /// Server is listening
            /// </summary>
            LISTEN,

            /// <summary>
            /// Server is not listening
            /// </summary>
            CLOSE
        }

        /// <summary>
        /// Enum for computer name format
        /// </summary>
        public enum ComputerNameFormat
        {
            /// <summary>
            /// The computer name net bios.
            /// </summary>
            ComputerNameNetBIOS,

            /// <summary>
            /// The computer name dns hostname.
            /// </summary>
            ComputerNameDnsHostname,

            /// <summary>
            /// The computer name dns domain.
            /// </summary>
            ComputerNameDnsDomain,

            /// <summary>
            /// The computer name dns fully qualified.
            /// </summary>
            ComputerNameDnsFullyQualified,

            /// <summary>
            /// The computer name physical net bios.
            /// </summary>
            ComputerNamePhysicalNetBIOS,

            /// <summary>
            /// The computer name physical dns hostname.
            /// </summary>
            ComputerNamePhysicalDnsHostname,

            /// <summary>
            /// The computer name physical dns domain.
            /// </summary>
            ComputerNamePhysicalDnsDomain,

            /// <summary>
            /// The computer name physical dns fully qualified.
            /// </summary>
            ComputerNamePhysicalDnsFullyQualified
        }

        #endregion

        #region Public Methods
        /// <summary>
        /// The is correct host name.
        /// </summary>
        /// <param name="hostName">
        /// Host name to check
        /// </param>
        /// <returns>
        /// true if it is a correct host name
        /// </returns>
        public static bool IsCorrectHostName(string hostName)
        {
            // Input
            var tempName = hostName;
            tempName = tempName.ToUpper();

            // Computer short name
            var shortName = Dns.GetHostName();
            shortName = shortName.ToUpper();

            // equal short name
            if (shortName.CompareTo(tempName) == 0)
            {
                return true;
            }

            // Get full computernamne
            uint size = 256;
            var builder = new StringBuilder((int)size);
            var success = GetComputerNameEx(ComputerNameFormat.ComputerNamePhysicalDnsFullyQualified, builder, ref size);
            if (success)
            {
                // call success
                var szfullName = builder.ToString();
                szfullName = szfullName.ToUpper();
                if (szfullName.CompareTo(tempName) == 0)
                {
                    // Equal long name
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// Check wheter a string prepresent an local host name
        /// </summary>
        /// <param name="hostName">
        /// The host name to check
        /// </param>
        /// <returns>
        /// true if the string prepresents localhost
        /// </returns>
        public static bool IsLocalhost(string hostName)
        {
            hostName = hostName.Trim();
            return hostName.ToUpper().CompareTo("LOCALHOST") == 0;
        }

        /// <summary>
        /// Check whether a string prepresent an IP address
        /// </summary>
        /// <param name="intProcAddr">
        /// IP Address string to check
        /// </param>
        /// <returns>
        /// true if the string is IP address
        /// </returns>
        public static bool IsIPAddress(string intProcAddr)
        {
            var myRegex = new Regex(@"^(([01]?\d\d?|2[0-4]\d|25[0-5])\.){3}([01]?\d\d?|25[0-5]|2[0-4]\d)$");
            return myRegex.IsMatch(intProcAddr);
        }

        /// <summary>
        /// The is loopback.
        /// </summary>
        /// <param name="intProcAddr">
        /// IP address string to check
        /// </param>
        /// <returns>
        /// true if it is loop back
        /// </returns>
        public static bool IsLoopback(string intProcAddr)
        {
            var ip = IPAddress.Parse(intProcAddr);
            if (ip == null)
            {
                return false;
            }

            return IPAddress.IsLoopback(ip);
        }

        /// <summary>
        /// External Get Computer name API call
        /// </summary>
        /// <param name="nameType">
        /// Computer name format type
        /// </param>
        /// <param name="buffer">
        /// Out string buffer of computer name
        /// </param>
        /// <param name="bufferSize">
        /// The Buffer size
        /// </param>
        /// <returns>
        /// true if get name ok
        /// </returns>
        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern bool GetComputerNameEx(
            ComputerNameFormat nameType, [Out] StringBuilder buffer, ref uint bufferSize);
        #endregion
    }
}
